use std::panic::Location;

use super::text::SourceLocation;
#[allow(unused)]
use super::text::TextSpan;

#[derive(Debug, PartialEq, Clone)]
pub enum KeywordType {
    Loop,
    While,
    Var,
    Return,
    If,
    Else,
    Switch,
    Case,
    Default,
    Continue,
    Break,
    True,
    False,

    Nil,
}

#[derive(Debug, PartialEq, Clone)]
pub enum SyntaxKind {
    Unknown,

    Number,

    Assignment, //赋值;

    // ======比较==========;
    Equals,        //== 等于;
    BangEquals,    // != 不等于;
    Greater,       //>  大于;
    GreaterEquals, //>= 大于等于;
    Less,          //<  小于;
    LessEquals,    //<= 小于等于;

    // =======运算符=======;
    // +,-,*,/,%;
    Plus,     //+ 加号/正号;
    Minus,    //- 减号/负号;
    Asterisk, //* 星号/乘号;
    Slash,
    /// 斜杠/除号;
    Percent, //% 百分号/取余;

    // 逻辑运算;
    Bang,   // !  非;
    Or,     // || 与;
    BitOr,  // |  或
    And,    // && 且;
    BitAnd, // &  //与取地址相同;

    // ====== 符号 ========;
    Whitespace, //空白符;

    Tilde,     //~ 波浪号;
    Colon,     //: 冒号;
    Comma,     //, 逗号;
    Dot,       //. 点;
    Semicolon, //; 分号;

    // ========括号========;
    //();
    OpenParenthesis,  //( 左 圆括号;
    CloseParenthesis, //) 右 圆括号;;
    //[];
    OpenBracket,  //[ 左 方括号;
    CloseBracket, //] 右 方括号;
    //{};
    OpenBrace,  //{ 左 花括号;
    CloseBrace, //} 右 花括号;

    //标识符
    Identifier, //标识符:_asdad,asdaeg _a12312;

    //keyword;
    // function;
    Func,
    If,
    For,
    Var,
    Else,
    Break,
    While,
    Return,

    //Keyword(KeywordType),
    /// '// XXX '   单行;
    /// '/* XXX */' 多行
    Comments, // 注释LineComment ,BlockComment ;

    //字符串" sasdasdasd "";
    String,
    //字节' ';
    Char,

    // end of file;
    Eof,
}

#[derive(Debug, Clone, PartialEq)]
pub struct SyntaxToken {
    pub kind: SyntaxKind,
    pub span: TextSpan,
    pub local: SourceLocation,
}

impl SyntaxToken {
    pub fn new(_kind: SyntaxKind, _span: TextSpan, _loc: SourceLocation) -> Self {
        Self {
            kind: _kind,
            span: _span,
            local: _loc,
        }
    }

    pub fn is(&self, kind: SyntaxKind) -> bool {
        self.kind == kind
    }
    pub fn as_string(&self) -> &String {
        &self.span.literal
    }
}
